package de.szut.ita13sommerfeld.apacheanalyser.handler;

import java.io.IOException;

import de.szut.ita13sommerfeld.apacheanalyser.apachelog.ApacheLog;
import de.szut.ita13sommerfeld.apacheanalyser.apachelog.Date;
import de.szut.ita13sommerfeld.apacheanalyser.apachelog.Entry;
import de.szut.ita13sommerfeld.apacheanalyser.apachelog.User;
import de.szut.ita13sommerfeld.apacheanalyser.components.ApacheComponent;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.EntryLibary;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.MethodLibary;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.ResourceLibary;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.StatusLibary;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.UserLibary;
import de.szut.ita13sommerfeld.apacheanalyser.reader.ApacheReader;

/**
 * 
 * @author Rene Sommerfeld
 *
 */

public class ApacheHandler implements ApacheComponent {

	private ApacheLog log;
	private ApacheReader apachereader;
	private EntryLibary entrylibary;
	
	private UserLibary userLibary;
	private MethodLibary methodLibary;
	private ResourceLibary resourceLibary;
	private StatusLibary statusLibary;
	
	/**
	 * 
	 * @param log the log that will be analyzed
	 */
	public ApacheHandler(ApacheLog log) {
		this.log = log;
		this.apachereader = log.getApachereader();
		this.entrylibary = log.getEntries();
		this.userLibary  = log.getUserlibary();
		this.methodLibary = log.getMethodlibary();
		this.resourceLibary = log.getResourcelibary();
		this.statusLibary = log.getStatuslibary();
	}
	
	/**
	 * 
	 * @return returns the log object with analyzed statistics
	 */
	public ApacheLog startAnalyzing() {
		// sets the current millis to the log process time
		log.setProcesstime(System.currentTimeMillis());
		// while the log has a line left the reader reads a next line
		while(apachereader.hasNextLogLine()) { 
			//contains the next log line
			String line = apachereader.getNextLogLine(); 
			//the LineParser parsing the line to an Entry
			Entry entry = LineParser.getEntryFromLogLine(line); 
			//if the entry has no failure it gets add to entrylibary
			if(entry != null) 
				entrylibary.add(entry);
			else 
				//if the entry has a failure the current line number gets add to the defective lines list in the entrylibary
				entrylibary.getDefectiveLines().add(log.getLines() + 1); 
			//increments the line number
			log.incrementLines(); 
		}
		//closes the log reader
		try {
			apachereader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		//loop to all entries in the entrylibary
		for(Entry entry : entrylibary) {
			if(entry != null) {
				String currentIP = entry.getIp();
				String currentResource = entry.getResource();
				String currentMethod = entry.getMethod();
				Date currentDate = entry.getDate();
				int size = entry.getSize();
				int currentStatus = entry.getStatus();
				int statusType = currentStatus / 100;
				//if the userlibary doesnt contain the IP a new user gets add to it
				if(!userLibary.containsKey(currentIP)) {
					User user = new User(currentIP, currentDate, currentDate);
					user.setFirstAction(entry.getDate());
					user.getEntries().add(entry);
					user.addDataSize(size);
					User.addResource(user, currentResource);
					userLibary.put(currentIP, user);
				} else {
					User user = userLibary.get(currentIP);
					user.getEntries().add(entry);
					user.addDataSize(size);
					User.addResource(user, currentResource);
					user.setLastAction(currentDate);
				}
				ResourceLibary.addResourceToLibary(currentResource, resourceLibary);
				StatusLibary.addStatusToLibary(statusType, currentStatus, statusLibary);
				MethodLibary.addMethodToLibary(currentMethod, methodLibary);
				//adds the size of the current resource to total
				log.addData(size);
			}
		}
		//sets the process time to the distance between the start and end time
		log.setProcesstime(System.currentTimeMillis() - log.getProcesstime());
		return log;
	}
}
